﻿using MediatR;
using Microsoft.EntityFrameworkCore;
using Sgr.Domain.Uow.Database;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Sgr.EntityFrameworkCore
{
    public class EfCoreDatabaseApi : IDatabaseApi, ISupportsSavingChanges
    {
        private readonly IMediator _mediator;
        private readonly UnitOfWorkDbContext _dbContext;

        public UnitOfWorkDbContext DbContext => _dbContext;

        public EfCoreDatabaseApi(
            UnitOfWorkDbContext dbContext,
            IMediator mediator)
        {
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
            _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
        }

        public async Task SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            // 选择 A) 在提交数据前执行领域事件
            // - 优点：所有操作在同一个事务中
            // - 适用于领域事件处理器使用相同 DbContext 的场景

            // 选择 B) 在提交数据后执行领域事件
            // - 会产生多个事务
            // - 需要处理最终一致性
            // - 需要处理补偿操作

            await _mediator.DispatchDomainEventsAsync(_dbContext);

            //this.ChangeTracker.DetectChanges();

            // After executing this line all the changes (from the Command Handler and Domain Event Handlers)
            // performed through the DbContext will be committed
            await _dbContext.SaveChangesAsync(cancellationToken);
        }
    }
}